﻿using System;
using System.Text;

using NORM.Common;
using NORM.DataBase;
using NORM.Entity;

using System.Collections.Generic;
using System.Reflection;
using System.Diagnostics;

namespace NORM.SQLObject
{
    public partial class OQL
    {
        public OQLJoin Join(EntityBase model)
        {
            OQLJoin joinentity = new OQLJoin(model);
            _join = true;            
            modelArray.Add(model);
            string t1 = string.Empty;//modelobject表的别名
            GetAsTableName(modelobject.TableName, out t1);
            string t2 = string.Empty;//model 表的别名
            GetAsTableName(model.TableName, out t2);
            this.sql += " FROM " + "[" + modelobject.TableName + "] " + t1 + " INNER JOIN [" + model.TableName + "] " + t2 + "";

            model.PropertyOnGetting += this.OnPropertyChanged;
            joinentity.mainOql = this;            
            return joinentity;
        }

        public OQLJoin LeftJoin(EntityBase model)
        {
            OQLJoin joinentity = new OQLJoin(model);
            _join = true;            
            modelArray.Add(model);
            string t1 = string.Empty;//modelobject表的别名
            GetAsTableName(modelobject.TableName, out t1);
            string t2 = string.Empty;//model 表的别名
            GetAsTableName(model.TableName, out t2);
            this.sql += " FROM " + "[" + modelobject.TableName + "] " + t1 + " LEFT JOIN [" + model.TableName + "] " + t2 + "";

            model.PropertyOnGetting += this.OnPropertyChanged;
            joinentity.mainOql = this;
            return joinentity;
        }

        public OQLJoin RightJoin(EntityBase model)
        {
            OQLJoin joinentity = new OQLJoin(model);
            _join = true;             
            modelArray.Add(model);
            string t1 = string.Empty;//modelobject表的别名
            GetAsTableName(modelobject.TableName, out t1);
            string t2 = string.Empty;//model 表的别名
            GetAsTableName(model.TableName, out t2);
            this.sql += " FROM " + "[" + modelobject.TableName + "] " + t1 + " RIGHT JOIN [" + model.TableName + "] " + t2 + "";

            model.PropertyOnGetting += this.OnPropertyChanged;
            joinentity.mainOql = this;
            return joinentity;
        }
        
        public OQL Where(object Field, object Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            this._conditions = null;
            GC.Collect();
            Condition condition = new Condition();
            condition.Field = fieldstring;
            condition.Value = Value;
            condition.Comparison = "=";
            return Where(new Condition[] { condition });
        }

        public OQL Where(object Field, string Comparison,  object Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            this._conditions = null;
            GC.Collect();
            Condition condition = new Condition();
            condition.Field = fieldstring;
            condition.Value = Value;
            condition.Comparison = Comparison;
            return Where(new Condition[] { condition });
        }

        public OQL And(object Field, object Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            List<Condition> conditions = new List<Condition>();
            if (this._conditions != null)
            {
                foreach (Condition c in this._conditions)
                {
                    conditions.Add(c);
                }

                this._conditions = null;
                GC.Collect();
            }

            Condition condition = new Condition();
            condition.Field = fieldstring;
            condition.Value = Value;
            conditions.Add(condition);

            return Where(conditions.ToArray());
        }

        public OQL And(object Field, string Comparison, object Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            List<Condition> conditions = new List<Condition>();
            if (this._conditions != null)
            {
                foreach (Condition c in this._conditions)
                {
                    conditions.Add(c);
                }

                this._conditions = null;
                GC.Collect();
            }

            Condition condition = new Condition();
            condition.Field = fieldstring;
            condition.Value = Value;
            condition.Comparison = Comparison;
            conditions.Add(condition);

            return Where(conditions.ToArray());
        }

        public OQL Or(object Field, object Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            List<Condition> conditions = new List<Condition>();
            if (this._conditions != null)
            {
                foreach (Condition c in this._conditions)
                {
                    conditions.Add(c);
                }

                this._conditions = null;
                GC.Collect();
            }

            Condition condition = new Condition();
            condition.Relation = "OR";
            condition.Field = fieldstring;
            condition.Value = Value;
            conditions.Add(condition);

            return Where(conditions.ToArray());
        }

        public OQL Or(object Field, string Comparison, object Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            List<Condition> conditions = new List<Condition>();
            if (this._conditions != null)
            {
                foreach (Condition c in this._conditions)
                {
                    conditions.Add(c);
                }

                this._conditions = null;
                GC.Collect();
            }

            Condition condition = new Condition();
            condition.Relation = "OR";
            condition.Field = fieldstring;
            condition.Comparison = Comparison;
            condition.Value = Value;
            conditions.Add(condition);

            return Where(conditions.ToArray());
        }

        public OQL In(object Field, string Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            List<Condition> conditions = new List<Condition>();
            if (this._conditions != null)
            {
                foreach (Condition c in this._conditions)
                {
                    conditions.Add(c);
                }

                this._conditions = null;
                GC.Collect();
            }

            Condition condition = new Condition();
            condition.Relation = "";
            condition.Field = fieldstring;
            condition.Comparison = "IN";
            condition.Value = Value;
            conditions.Add(condition);

            return Where(conditions.ToArray());
        }

        public OQL AndIn(object Field, string Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            List<Condition> conditions = new List<Condition>();
            if (this._conditions != null)
            {
                foreach (Condition c in this._conditions)
                {
                    conditions.Add(c);
                }

                this._conditions = null;
                GC.Collect();
            }

            Condition condition = new Condition();
            condition.Relation = "AND";
            condition.Field = fieldstring;
            condition.Comparison = "IN";
            condition.Value = Value;
            conditions.Add(condition);

            return Where(conditions.ToArray());
        }

        public OQL OrIn(object Field, string Value)
        {
            string fieldstring = Field + "";

            if (_join && this.fieldStack.Count > 0)
            {
                TableField tf = this.fieldStack.Pop();
                fieldstring = tf.Entity.TableName + "." + tf.Name;
            }

            List<Condition> conditions = new List<Condition>();
            if (this._conditions != null)
            {
                foreach (Condition c in this._conditions)
                {
                    conditions.Add(c);
                }

                this._conditions = null;
                GC.Collect();
            }

            Condition condition = new Condition();
            condition.Relation = "OR";
            condition.Field = fieldstring;
            condition.Comparison = "IN";
            condition.Value = Value;
            conditions.Add(condition);

            return Where(conditions.ToArray());
        }

    }
}
